#include "mytcpsocket.h"
#include "../myprofile.h"
#include "../serialport/myserialport.h"
#include "../utils/singleton.h"
#include <QJsonDocument>
#include <QJsonObject>

MyTcpSocket *MyTcpSocket::instance = nullptr;

MyTcpSocket::MyTcpSocket(QObject *parent) : QTcpSocket(parent) {
  connect(this, &MyTcpSocket::readyRead, this, &MyTcpSocket::readyReadSlot);

  connect(this, &MyTcpSocket::disconnected, this,
          &MyTcpSocket::disconnectedSlot);
}

void MyTcpSocket::send_sensor_data(SensorType type, double value1,
                                   double value2) {
  switch (type) {
  case SensorType::TEMP_WET: {
    this->write(QString(R"({"dev":2,"ret1":%1,"ret2":%2})")
                    .arg(value1)
                    .arg(value2)
                    .toStdString()
                    .c_str());
    MYPROFILE(
        ProfileType::TRACE,
        QString("发送 '温湿度', 数值1 %1, 数值2 %2").arg(value1).arg(value2));
    break;
  }
  case SensorType::CO2: {
    this->write(
        QString(R"({"dev":3,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 'CO2', 数值 %1").arg(value1));
    break;
  }
  case SensorType::LUX: {
    this->write(
        QString(R"({"dev":4,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 '光照', 数值 %1").arg(value1));
    break;
  }
  case SensorType::UVs: {
    this->write(
        QString(R"({"dev":5,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE,
              QString("发送 '紫外线', 数值 %1").arg(value1));
    break;
  }
  case SensorType::FRAG: {
    this->write(
        QString(R"({"dev":6,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 '烟雾', 数值 %1").arg(value1));
    break;
  }
  case SensorType::FIRE: {
    this->write(
        QString(R"({"dev":8,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 '火光', 数值 %1").arg(value1));
    break;
  }
  case SensorType::TEST_SEN: {
    this->write(
        QString(R"({"dev":0,"ret":%1})").arg(value1).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 '测试', 数值 %1").arg(value1));
    break;
  }
  case SensorType::CH4:
  case SensorType::BODY:
  case SensorType::ALL_SENSOR:
    break;
  }
}

void MyTcpSocket::send_excute_data(ExcuteType type, double value1,
                                   double value2) {
  switch (type) {
  case ExcuteType::LED: {
    int int_val1 = static_cast<int>(value1);
    int int_val2 = static_cast<int>(value2);
    this->write(QString(R"({"dev":1,"ret1":%1,"ret2":%2,"ret3":%3,"ret4":%4})")
                    .arg((int_val1 & 0xff00) >> 8)
                    .arg(int_val1 & 0xff)
                    .arg((int_val2 & 0xff00) >> 8)
                    .arg(int_val2 & 0xff)
                    .toStdString()
                    .c_str());
    MYPROFILE(ProfileType::TRACE,
              QString("发送 'LED', 数值1 %1, 数值2 %2, 数值3 %3, 数值4 %4")
                  .arg((int_val1 & 0xff00) >> 8)
                  .arg(int_val1 & 0xff)
                  .arg((int_val2 & 0xff00) >> 8)
                  .arg(int_val2 & 0xff));
  } break;
  case ExcuteType::FAN: {
    bool is_true = value1 > 0;
    this->write(
        QString(R"({"dev":11,"ret":%1})").arg(is_true).toStdString().c_str());
    MYPROFILE(ProfileType::TRACE, QString("发送 '风扇', 数值 %1").arg(is_true));
  } break;
  case ExcuteType::RELAY: {
    int relay_id = value1 > 0 ? 1 : 2;
    bool is_true = value2 > 0;
    this->write(QString(R"({"dev":12,"ret1":%1,"ret2":%2})")
                    .arg(relay_id)
                    .arg(is_true)
                    .toStdString()
                    .c_str());
    MYPROFILE(
        ProfileType::TRACE,
        QString("发送 '继电器', 数值 %1, 数值 %2").arg(relay_id).arg(is_true));
  } break;
  case ExcuteType::STEP: {
    bool is_on = (value1 > 0);
    this->write(QString(R"({"dev":13,"ret":%1})")
                    .arg(static_cast<bool>(is_on))
                    .toStdString()
                    .c_str());
    MYPROFILE(ProfileType::TRACE,
              QString("发送 '步进电机', 数值 '%1'").arg(is_on));
  } break;
  case ExcuteType::STEERING:
  case ExcuteType::TEST_EX:
  case ExcuteType::ALL_EXCUTE:
    //  default:
    break;
  }
}

void MyTcpSocket::readyReadSlot() {
  QByteArray data;
  data = this->readAll();
  qDebug() << data;
  handleData(data);
}

void MyTcpSocket::disconnectedSlot() { emit socketDisconnected(thread()); }

void MyTcpSocket::handleData(QByteArray data) {
  temp.append(data);
  int count = 0;
  for (int i = 0; i < temp.length(); i++) {
    if (temp.at(i) == '{') {
      if (count == 0) {
        temp = temp.mid(i, temp.length());
        i = 0;
        count++;
        continue;
      }
    }
    if (temp.at(i) == '}') {
      count--;
      if (count == 0) {
        QByteArray frame = temp.mid(0, i + 1);
        // 处理当前数据帧
        handleFrame(frame);
        temp = temp.mid(i + 1, temp.length());
        i = -1;
        continue;
      }
    }
  }
}

void MyTcpSocket::handleFrame(QByteArray data) {
  auto obj = QJsonDocument::fromJson(data).object();
  int devID = obj.value("dev").toInt();
  if (devID == 1) {
    // LED
    int led_1 = obj.value("val1").toInt();
    int led_2 = obj.value("val2").toInt();
    int led_3 = obj.value("val3").toInt();
    int led_4 = obj.value("val4").toInt();
    int light1, light2;
    light1 = (led_1 << 8) | led_2;
    light2 = (led_3 << 8) | led_4;
    SG_SERIALPORT()->request_excute(ExcuteType::LED, light1, light2);
    MYPROFILE(ProfileType::DOWN, QString("执行 %1 'LED', 行号1 亮度 '%2', "
                                         "行号2 亮度 '%3', "
                                         "行号3 亮度 '%4', "
                                         "行号4 亮度 '%5'")
                                     .arg(devID)
                                     .arg(led_1)
                                     .arg(led_2)
                                     .arg(led_3)
                                     .arg(led_4));
  } else if (devID == 11) {
    // 风扇
    bool is_true = obj.value("val").toBool();
    SG_SERIALPORT()->request_excute(ExcuteType::FAN, is_true ? 1.0 : -1.0);
    MYPROFILE(
        ProfileType::TRACE,
        QString("执行 %1 '风扇' %2").arg(devID).arg(is_true ? "打开" : "关闭"));
  } else if (devID == 12) {
    // 继电器
    int relay_id = obj.value("val1").toInt();
    bool is_true = obj.value("val2").toBool();
    SG_SERIALPORT()->request_excute(
        ExcuteType::RELAY, relay_id == 1 ? 1.0 : -1.0, is_true ? 1.0 : -1.0);
    MYPROFILE(ProfileType::DOWN, QString("执行 %1 '继电器', %2号 %3")
                                     .arg(devID)
                                     .arg(relay_id)
                                     .arg(is_true ? "打开" : "关闭"));
  } else if (devID == 13) {
    // 步进电机
    bool is_on = obj.value("val").toBool();
    SG_SERIALPORT()->step_on(is_on);
    MYPROFILE(ProfileType::DOWN, QString("执行 %1 '步进电机', %2")
                                     .arg(devID)
                                     .arg(is_on ? "打开" : "关闭"));
  } else {
    // 其他发送
    MYPROFILE(ProfileType::WARNING,
              QString("未知执行设备 '%1', 可能是传感发送").arg(devID));
  }
}
